package com.example.criminalintent.model

import android.annotation.SuppressLint
import android.app.Activity
import android.content.ContentValues
import android.content.Context
import android.database.sqlite.SQLiteDatabase
import com.example.criminalintent.db.CrimeBaseHelper
import com.example.criminalintent.db.CrimeCursorWrapper
import com.example.criminalintent.model.CrimeDbSchema.CrimeTable
import com.example.criminalintent.model.CrimeDbSchema.CrimeTable.NAME
import java.io.File
import java.util.*
import kotlin.collections.ArrayList


class CrimeLab private constructor(context: Context) {

    private var mContext: Context = context.applicationContext
    private var mDatabase: SQLiteDatabase? = null

    init {
        mDatabase = CrimeBaseHelper(mContext).writableDatabase
    }

    companion object {

        @SuppressLint("StaticFieldLeak")
        private var sCrimeLab: CrimeLab? = null

        operator fun get(context: Activity): CrimeLab {
            if (sCrimeLab == null) {
                sCrimeLab = CrimeLab(context)
            }
            return sCrimeLab as CrimeLab
        }
    }


    fun getCrimes(): MutableList<Crime> {
        val crimes: MutableList<Crime> = ArrayList()

        val cursorWrapper = queryCrimes(null, null)
        cursorWrapper.use {
            it.moveToFirst()
            while (!it.isAfterLast) {
                crimes.add(it.getCrime()!!)
                it.moveToNext()
            }
        }
        return crimes
    }

    fun getCrime(id: UUID): Crime? {
        val cursor = queryCrimes(
            CrimeTable.Cols.UUID + " = ?",
            arrayOf(id.toString())
        )
        cursor.use {
            if (it.count == 0) {
                return null
            }
            cursor.moveToFirst()
            return cursor.getCrime()
        }
    }

    fun addCrime(crime: Crime) {
        val values = getContentValues(crime)
        mDatabase!!.insert(NAME, null, values)
    }

    fun updateCrime(crime: Crime) {
        val id = crime.mId.toString()
        val contentValues = getContentValues(crime)
        mDatabase!!.update(
            NAME, contentValues,
            CrimeTable.Cols.UUID + " = ?",
            arrayOf(id)
        )
    }

    fun getPhotoFile(crime: Crime): File {
        val dir = mContext.filesDir
        return File(dir, crime.getPhotoFilename())
    }


    private fun queryCrimes(whereClause: String?, whereArgs: Array<String>?): CrimeCursorWrapper {
        val query = mDatabase!!.query(NAME, null, whereClause, whereArgs, null, null, null)
        return CrimeCursorWrapper(query)
    }


    private fun getContentValues(crime: Crime): ContentValues {
        val contentValues = ContentValues()
        contentValues.put(CrimeTable.Cols.UUID, crime.mId.toString())
        contentValues.put(CrimeTable.Cols.TITLE, crime.mTitle)
        contentValues.put(CrimeTable.Cols.DATE, crime.mDate!!.time)
        contentValues.put(CrimeTable.Cols.SOLVED, crime.mSolved)
        contentValues.put(CrimeTable.Cols.SUSPECT, crime.mSuspect)
        return contentValues
    }
}